package com.is.add.service.impl;


import com.is.add.controller.vo.RankingDataVO;
import com.is.add.controller.vo.ServerGroupStatusVO;
import com.is.add.controller.vo.ServerStatusVO;
import com.is.add.enmus.MonitorUrlEnum;
import com.is.add.enmus.OrderStatus;
import com.is.add.enmus.TimeType;
import com.is.add.mapper.ServerListMapper;
import com.is.add.mapper.ServerMonitorMapper;
import com.is.add.model.*;
import com.is.add.service.GoodsService;
import com.is.add.service.MonitorService;
import com.is.add.service.OldGoodsService;
import com.is.add.service.OrderService;
import com.is.add.util.DateUtil.DateStyle;
import com.is.add.util.DateUtil.DateUtil;
import com.is.add.util.DimensionUtil.DataCount;
import com.is.add.util.KeyValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

@Service
public class MonitorServiceImpl implements MonitorService {

    private static int TopNum = 10;                  //排行榜
    @Autowired
    private OrderService orderService;
    @Autowired
    private ServerMonitorMapper serverMonitorMapper;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private OldGoodsService oldGoodsService;
    @Autowired
    private ServerListMapper serverListMapper;

    /**
     * 监控服务器状态
     * @param sign                  请求识别码
     * @return                      ServerStatusVO
     */
    @Override
    public ServerGroupStatusVO monitorServer(String sign) {
        ServerGroupStatusVO serverGroupStatusVO = new ServerGroupStatusVO();
        serverGroupStatusVO.setSign(sign);
        serverGroupStatusVO.setDateTime(DateUtil.DateToString(new Date(),DateStyle.YYYY_MM_DD_HH_MM_SS));
        List<ServerStatusVO> serverStatusVOs = new ArrayList<>();
        int successNum = 0;
        int failureNum = 0;
        Example serverExample = new Example(ServerList.class);
        serverExample.createCriteria().andEqualTo("hasMonitor",true);
        List<ServerList> serverLists = this.serverListMapper.selectByExample(serverExample);
        for (ServerList v: serverLists) {
            ServerMonitor serverMonitor = this.serverMonitorMapper.getRecentlyMonitorMessage(v.getId().intValue(), v.getServerName());
            if (serverMonitor != null) {
                if (serverMonitor.getServerStatus().equals("SUCCESS")) {
                    successNum++;
                } else {
                    failureNum++;
                }
                serverStatusVOs.add(new ServerStatusVO(v.getServerName(), v.getUrlName(), serverMonitor.getServerStatus(), serverMonitor.getMonitorResultMessage()));
            }
        }
        serverGroupStatusVO.setSuccessNum(successNum);
        serverGroupStatusVO.setFailureNum(failureNum);
        serverGroupStatusVO.setServerStatusList(serverStatusVOs);
        return serverGroupStatusVO;
    }

    /**
     * 保存监控信息
     * @param serverMonitor         服务器监控信息对象
     */
    @Override
    public void save(ServerMonitor serverMonitor) {
        this.serverMonitorMapper.insertSelective(serverMonitor);
    }

    /**
     * 统计排行榜数据
     * @param sign              识别码
     * @return                  RankingDataVO
     */
    @Override
    public RankingDataVO dayCountRankingData(String sign) {
        Date nowDateTime = new Date();
        String nowDate = DateUtil.DateToString(nowDateTime, DateStyle.YYYY_MM_DD_HH_MM_SS);         //当前日期
        List<Date> thisWeek = DateUtil.dateToWeek(nowDateTime); //当前周日期
        String earlyMonth = DateUtil.getYear(nowDateTime)+"-"+String.format("%02d",DateUtil.getMonth(nowDateTime))+"-"+"01";   //月初
        Map<String,String> map =new HashMap<>();
        map.put("groups","1");
        map.put("orderStatus", OrderStatus.VerifiedDateOut.name());
        map.put("timeType", TimeType.examineTime.name());

        RankingDataVO rankingDataVO = new RankingDataVO();
        rankingDataVO.setSign(sign);
        rankingDataVO.setDateTime(nowDate);
        //当天数据
        map.put("startTime",DateUtil.getDate(nowDateTime)+" 00:00:00");
        map.put("endTime",nowDate);
        OrderRankingData dayData = this.orderService.sumRecentlyOrderBase(map);
        if (dayData != null) {
            rankingDataVO.setDayPaySum(dayData.getTotalPaySum());
            rankingDataVO.setDaySubsidySum(dayData.getTotalSubsidySum());
            rankingDataVO.setDayTotalSum(dayData.getTotalPaySum()+dayData.getTotalSubsidySum());
        }else {
            rankingDataVO.setDayPaySum(0.0);
            rankingDataVO.setDaySubsidySum(0.0);
            rankingDataVO.setDayTotalSum(0.0);
        }

        //当周数据
        Map<String,String> mapWeek =new HashMap<>();
        mapWeek.put("startTime",DateUtil.getDate(thisWeek.get(0))+" 00:00:00");
        mapWeek.put("endTime",nowDate);
//        mapWeek.put("endTime",DateUtil.getDate(thisWeek.get(6))+" 23:59:59");
        OrderRankingData weekData = this.orderService.sumRecentlyOrderBase(mapWeek);
        if (weekData != null) {
            rankingDataVO.setWeekPaySum(weekData.getTotalPaySum());
            rankingDataVO.setWeekSubsidySum(weekData.getTotalSubsidySum());
            rankingDataVO.setWeekTotalSum(weekData.getTotalPaySum() + weekData.getTotalSubsidySum());
        }else {
            rankingDataVO.setWeekPaySum(0.0);
            rankingDataVO.setWeekSubsidySum(0.0);
            rankingDataVO.setWeekTotalSum(0.0);
        }
        /*
        //当月数据
        Map<String,String> mapMonth =new HashMap<>();
        mapMonth.put("startTime",DateUtil.getDate(earlyMonth+" 00:00:00"));
        mapMonth.put("endTime",DateUtil.getDate(nowDate+" 23:59:59"));
        OrderRankingData monthData = this.orderMapper.sumAllOrderBase(mapMonth);
        rankingDataVO.setMonthPaySum(monthData.getTotalPaySum());
        rankingDataVO.setMonthSubsidySum(monthData.getTotalSubsidySum());
        rankingDataVO.setMonthTotalSum(monthData.getTotalPaySum()+monthData.getTotalSubsidySum());
        */

        //当月数据
        map.put("startTime",earlyMonth+" 00:00:00");
        map.put("endTime",nowDate);
        String[] dimensionList ={"sales","shop"};
        DataCount monthData = this.orderService.getRecentlyOrder(dimensionList,map);
        if (monthData != null) {
            rankingDataVO.setMonthPaySum(monthData.getPaySum());
            rankingDataVO.setMonthSubsidySum(monthData.getSubsidySum());
            rankingDataVO.setMonthTotalSum(monthData.getTotalSum());
            rankingDataVO.setSalesmanTotalSumRanking(this.salesmanTotalSumSort(monthData.getSubSettlements()));
            rankingDataVO.setSalesmanSubsidyRateRanking(this.salesmanSubsidyRateSort(monthData.getSubSettlements()));
            //rankingDataVO.setShopBookingRateRanking(this.shopBookingRateSort(map));
        }else {
            rankingDataVO.setMonthPaySum(0.0);
            rankingDataVO.setMonthSubsidySum(0.0);
            rankingDataVO.setMonthTotalSum(0.0);
        }
        rankingDataVO.setShopBookingRateRanking(this.shopBookingRanking(map.get("startTime"),map.get("endTime")));
        return rankingDataVO;
    }

    /**
     * 场馆预订率Top3
     * @return                  场馆名称-预订率
     * @param map               条件
     */
    private List<KeyValue> shopBookingRateSort(Map<String, String> map) {
        List<KeyValue> shopGoodsList = new ArrayList<>();
        List<KeyValue> salesmanSubsidyTopNum = new ArrayList<>();
        String[] dimensionList ={"shop"};
        DataCount monthShopData = this.orderService.getRecentlyOrder(dimensionList,map);
        for (DataCount dataCount : monthShopData.getSubSettlements()) {
            Integer shopGoods = 0;
            Integer shopId = Integer.valueOf(dataCount.getValue());
            //7天前goods历史
            List<OldGoods> oldGoodsList = this.oldGoodsService.findOldGoodsByShopAndDate(shopId, map.get("startTime"), map.get("endTime"));
            for (OldGoods g : oldGoodsList) {
                shopGoods += g.getTotalNum();
            }
            //已上线7天内goods
            List<Goods> goodsList = this.goodsService.findGoodsByShopAndDate(shopId, map.get("startTime"), map.get("endTime"));
            for (Goods g : goodsList) {
                shopGoods += g.getTotalNum();
            }
            if (shopGoods != 0) {
                shopGoodsList.add(new KeyValue(dataCount.getTitle(), String.format("%.2f", dataCount.getOrderNum() * 1.0 / shopGoods)));
            }

        }

        Collections.sort(shopGoodsList, new Comparator<KeyValue>(){
            public int compare(KeyValue arg0, KeyValue arg1) {
                return (Double.valueOf(arg0.getValue()).compareTo(Double.valueOf(arg1.getValue())));
            }
        });
        ListIterator<KeyValue> desc =shopGoodsList.listIterator(shopGoodsList.size());          //倒序
        for (int i = 0; i < TopNum; i++) {
            if (desc.hasPrevious()) {
                KeyValue tempKeyValue = desc.previous();
                salesmanSubsidyTopNum.add(tempKeyValue);
            }
        }
        return salesmanSubsidyTopNum;
    }

    private List<KeyValue> shopBookingRanking(String startTime, String endTime) {
        List<KeyValue> shopBookingRateTopNum = new ArrayList<>();
        Map<String,Object> map =new HashMap<>();
        map.put("startTime",startTime);
        map.put("endTime",endTime);
        map.put("topNum",TopNum);
        List<ShopBookingRankingData> shopBookingRankingDataList = this.oldGoodsService.selectShopBookingRate(map);
        for (ShopBookingRankingData data : shopBookingRankingDataList){
            if (data.getShopBookingRate() > 1.0){
                shopBookingRateTopNum.add(new KeyValue(data.getShopName(), "1.00"));
            }else {
                shopBookingRateTopNum.add(new KeyValue(data.getShopName(), String.format("%.2f", data.getShopBookingRate())));
            }
        }
        return shopBookingRateTopNum;
    }

    /**
     * 业务员补贴占比Top3
     * @param salesman          业务员维度统计数据
     * @return                  业务员-补贴占比
     */
    private List<KeyValue> salesmanSubsidyRateSort(List<DataCount> salesman) {
        List<KeyValue> salesmanSubsidyRateTop = new ArrayList<>();
        Collections.sort(salesman, new Comparator<DataCount>(){
            public int compare(DataCount arg0, DataCount arg1) {
                return (Double.valueOf(arg0.getTotalSum()/arg0.getSubsidySum())).compareTo(arg1.getTotalSum()/arg1.getSubsidySum());
            }
        });
        ListIterator<DataCount> desc =salesman.listIterator(salesman.size());          //倒序
        while (salesmanSubsidyRateTop.size() < TopNum && desc.hasPrevious()) {
            DataCount temp = desc.previous();
            if (temp.getSubsidySum() != 0)
            salesmanSubsidyRateTop.add(new KeyValue(temp.getValue(), String.format("%.2f", (temp.getTotalSum() / temp.getSubsidySum()))));
        }
        return salesmanSubsidyRateTop;
    }

    /**
     * 业务员总金额Top3
     * @param salesman              业务员维度统计数据
     * @return                      业务员-总金额
     */
    private List<KeyValue> salesmanTotalSumSort(List<DataCount> salesman){
        List<KeyValue> salesmanTotalSumTop = new ArrayList<>();
        Collections.sort(salesman, new Comparator<DataCount>(){
            public int compare(DataCount arg0, DataCount arg1) {
                return (Double.valueOf(arg0.getTotalSum())).compareTo(arg1.getTotalSum());
            }
        });
        ListIterator<DataCount> desc =salesman.listIterator(salesman.size());          //倒序
        while (salesmanTotalSumTop.size() < TopNum && desc.hasPrevious()) {
            DataCount temp = desc.previous();
            salesmanTotalSumTop.add(new KeyValue(temp.getValue(),String.valueOf(temp.getTotalSum())));
        }
        /*for (int i = 0; i < TopNum; i++) {
            if (desc.hasPrevious()) {
                DataCount temp = desc.previous();
                salesmanTotalSumTop.add(new KeyValue(temp.getValue(),String.valueOf(temp.getTotalSum())));
            }
        }*/
        return salesmanTotalSumTop;
    }
}